package org.fungene.services.kegg;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import net.sf.json.JSONObject;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;

import keggapi.KEGGLocator;
import keggapi.KEGGPortType;

public class KEGGLauncher {
	
	private static Statement stmt;
	private static Connection furnDB;
	private String[] geneList;

	public KEGGLauncher() {
		super();
	}

	public KEGGLauncher(String[] geneList) {
		super();
		this.geneList = geneList;
	}

	public String launch() {
		try {
			KEGGLocator locator = new KEGGLocator();
			KEGGPortType keggServer = locator.getKEGGPort();
			// KEGG需要使用自身拥有的ID系统进行查询。
			String[] KEGGIDs = new String[this.geneList.length];
			String KEGGID = new String();
			for (int i = 0; i < KEGGIDs.length; i++) {
				// 去服务器抽取ID对应信息
				if(i != 0)
					KEGGID += ";";
				KEGGID += KEGGIDs[i] = KEGGIDConverter(this.geneList[i]);
			}
			// 根据KEGG ID获得Pathway
			String[] results = keggServer.get_pathways_by_genes(KEGGIDs);
			if (results.length == 0)
				System.err.println("Pathway not found.");
			JSONObject resultJSON = new JSONObject();
			JSONObject retJSON = new JSONObject();
			String[] resultName = getPathName(results);
			for(int i = 0; i < results.length; i++){
				retJSON.clear();
				retJSON.put("pathway", results[i]);
				retJSON.put("pathname", resultName[i]);
				resultJSON.accumulate("pathways", retJSON);
			}
			
			resultJSON.put("KEGGIDs", KEGGID);
			return resultJSON.toString();
		} catch (Exception ex) {
		ex.printStackTrace();
			
			System.err.println("Error");
			return "";
		}
	}

	private String KEGGIDConverter(String symbolName) {
		String URL = "http://www.genome.jp/dbget-bin/www_bfind_sub?"
				+ "mode=bfind" + "&max_hit=1" + "&serv=kegg" + "&dbkey=genes"
				+ "&keywords=" + symbolName + "+hsa" + "&page=1";

		try {
			HttpClient httpClient = new HttpClient();
			GetMethod get = new GetMethod(URL);
			httpClient.executeMethod(get);
			String HTML = get.getResponseBodyAsString();

			String regex = "<a href=\"/dbget-bin/www_bget\\?hsa\\+\\d+\">(hsa:\\d+)([^;]+);";
			Pattern pattern = Pattern.compile(regex);
			Matcher matcher = pattern.matcher(HTML);
			if (matcher.find()) {
				if (matcher.group(2).contains(symbolName))
					return matcher.group(1);
			}
			return "";
		} catch (Exception ex) {
			System.out.println("ERROR");
			return "";
		}
	}
	
	private static String[] getPathName(String[] results){
		conn();
		String[] ret = new String[results.length];
		for(int i = 0; i < results.length; i++){
			results[i] = results[i].substring(5);
			try {
				ResultSet temp = stmt.executeQuery("select name from pathwayname where pathway = '" + results[i] + "'");
				if(temp.next()){
					ret[i] = temp.getString(1);
				}
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		closeconn();
		return ret;
	}
	
	public static void conn() {
		String databaseName = new String("keggparse");
		String serverIP = new String("166.111.134.70");
		String serverPort = new String("3306");
		try {
			Class.forName("org.gjt.mm.mysql.Driver").newInstance(); 
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		try {
			String URL = "jdbc:mysql://" + serverIP + ":" + serverPort + "/" + databaseName;
			String username = "root";
			String password = "BioFusion";
			
			furnDB = DriverManager.getConnection(URL, username, password);
			stmt = furnDB.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
					ResultSet.CONCUR_READ_ONLY);
		}catch(SQLException e) {
			e.printStackTrace();
			System.out.println("There was a problem connection to the database");
		}
	}
	
	public static void closeconn(){
		try {
			stmt.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}
